import { debugLogger } from "./logger";

export class ParameterBase {
  predictValue: number;
  private lastActualValue: number | null = null;
  private lastPredictedValue: number | null = null;
  private name = ''
  private min;
  private max;
  constructor(
    name: string,
  ) { 
    this.name = name;
    // this.min = -0.9;
    // this.max = 0.9;
  }

  optimizeAndPredictParameter(newValue: number): number {
    const currentActualValue = newValue;

    if (this.lastActualValue === null) {
      // Initial value, no processing
      this.lastActualValue = currentActualValue;
      return currentActualValue;
    }

    const percentageChangeActual = (currentActualValue - this.lastActualValue) / Math.abs(this.lastActualValue);
    
    if (this.lastPredictedValue === null) {
      // No previous prediction, predict based on the observed percentage change
      const predictedValue = currentActualValue * (1 + percentageChangeActual);
      this.lastPredictedValue = predictedValue;
      this.lastActualValue = currentActualValue;
      console.log(newValue, this.lastPredictedValue, currentActualValue, percentageChangeActual)
      return predictedValue;
    }

    const percentageChangePrediction = (this.lastPredictedValue - this.lastActualValue) / Math.abs(this.lastActualValue);

    const adjustment = percentageChangeActual - percentageChangePrediction;

    let predictedValue = this.lastPredictedValue * (1 + percentageChangeActual + adjustment);

    if (this.min && predictedValue < this.min) {
      predictedValue = this.min;
    } else if (this.max && predictedValue > this.max) {
      predictedValue = this.max;
    }

    this.lastPredictedValue = predictedValue;
    this.lastActualValue = currentActualValue;

    // console.log(`Parameter ${this.name} ${currentActualValue} -> optimized to ${predictedValue}`)
    // debugLogger(`Parameter ${this.name} optimized to ${predictedValue}`);
    return predictedValue;
  }

  public getPredictValue() {
    return this.predictValue;
  }
}



// typescript 
// 参数优化器
// 1. 输入默认参数值，输入下一个实际参数，根据实际参数值预测下一个参数
// 2. 需要加入记忆能力，记忆长度可以设置，可参考长短记忆的思想设计
// 3. 一轮完成训练
// 使用示例
const initialParams = [100, 1000];
const optimizer = new ParameterBase('test');


// 训练
optimizer.optimizeAndPredictParameter(-0.001); // 初始值，不做处理
optimizer.optimizeAndPredictParameter(-0.002); // 与上次实际值增长10%， 上一次没有预测值，直接预测下一个增长10%，下一个预测值是 110 * 1.1 = 121
optimizer.optimizeAndPredictParameter(-0.004); // 与上次实际值增长18.1%，比上一次预测多出 0.181 - 0.1 = 0.081，则在增长18.1%的基础上增加8.1%，下一个预测值为 130 * (1.181 + 0.081) = 164.06
optimizer.optimizeAndPredictParameter(-0.005); // 与上次实际值-23%，比上一次预测值少-39% ((164.06 - 100) / 164.06)，则下次预测值为 100 * (1 - 0.39) = 61
optimizer.optimizeAndPredictParameter(-0.006);
// 优化后
// 新的结果，尽可能接近
